package com.example.onlinereadingsystem.demos.web.util;

import java.io.*;
import java.util.Random;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.UUID;

/**
 * @Description
 * @Author ljm
 * @Date 2024/10/17
 */
@Component
@Slf4j
public class AliOSSUtils {
    // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    // 从环境变量中获取RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;
    // 填写Bucket名称，例如examplebucket。
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    /**
     * 生成一个唯一的file名称
     */
    public static String generateUniqueFileName(String prefix, String originalFilename) {
        if (Strings.isEmpty(originalFilename)) {
            log.error("非法文件上传！");
            throw new RuntimeException("非法文件上传！");
        }
        String randomName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        // 连接以形成一个唯一的 Bucket 名称
        return prefix + "-" + randomName;
    }

    // 创建OSSClient实例
    private OSS createOssClient() {
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
        return OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .region(bucketName)
                .build();
    }


    /**
     * @auther ljm
     * @create 2025/1/6
     * @describe OSS文件删除
     */
    public Boolean delete(String folderName, String fileName) {
        // 创建 OSSClient 实例
        OSS ossClient = createOssClient();
        try {
            String objectName = folderName + "/" + fileName;
            ossClient.deleteObject(bucketName, objectName);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return true;
    }

    /**
     * @auther ljm
     * @create 2025/1/6
     * @describe OSS文件上传
     */
    public String upload(MultipartFile file, String folderName) {
        //获取上传文件的输入流
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            log.error("文件上传失败！");
            throw new RuntimeException(e);
        }
        String originalFilename = file.getOriginalFilename();
        // System.out.println("!!!orignalFilename: " + originalFilename);
        // 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String fileName = generateUniqueFileName(folderName, originalFilename);
        // System.out.println("!!!objectName: " + objectName);
        // 创建OSSClient实例。
        OSS ossClient = createOssClient();
        String objectName = generateUniqueFileName(folderName, originalFilename);
        if (!Strings.isEmpty(folderName)) {
            objectName = folderName + "/" + fileName;
        } else {
            objectName = fileName;
        }

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message: " + oe.getErrorMessage());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            ossClient.shutdown();
        }
        // System.out.println("!!!url: " + url);
        return "https://" + bucketName + ".oss-cn-hangzhou.aliyuncs.com/" + folderName + "/" + fileName;
    }

}
